package com.hexinfo.dmpro.sparing.service.impl;

import cn.hutool.core.util.StrUtil;
import com.hexinfo.dmpro.common.utils.ScanCommonConstants;
import com.hexinfo.dmpro.sparing.dto.CreateTableDTO;
import com.hexinfo.dmpro.sparing.service.ImpalaService;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ImpalaServiceImpl implements ImpalaService {
    @Value("${conn.pool.impala.source.driverClassName}")
    private String driverJQ ;
    @Value("${conn.pool.impala.source.url}")
    private String urlJQ ;
    @Value("${conn.pool.impala.source.username}")
    private String usernameJQ ;
    @Value("${conn.pool.impala.source.password}")
    private String passwordJQ ;



    @Value("${conn.pool.impala.target.driverClassName}")
    private String driver ;
    @Value("${conn.pool.impala.target.url}")
    private String url ;
    @Value("${conn.pool.impala.target.username}")
    private String username ;
    @Value("${conn.pool.impala.target.password}")
    private String password ;


    @Value("${conn.pool.hive.source.driverClassName}")
    private String driverHiveJQ ;
    @Value("${conn.pool.hive.source.url}")
    private String urlHiveJQ ;
    @Value("${conn.pool.hive.source.username}")
    private String usernameHiveJQ ;
    @Value("${conn.pool.hive.source.password}")
    private String passwordHiveJQ ;

    @Value("${conn.pool.hive.target.driverClassName}")
    private String driverHive ;
    @Value("${conn.pool.hive.target.url}")
    private String urlHive ;
    @Value("${conn.pool.hive.target.username}")
    private String usernameHive ;
    @Value("${conn.pool.hive.target.password}")
    private String passwordHive ;
    @Value("${hdfs.tarPrefix}")
    private String tarPrefix;

    @Override
    public String dele(String sql) {
        boolean bol = false;
        try {
            Class.forName(driver);
            @Cleanup Connection conn = DriverManager.getConnection(url,username,password);
            @Cleanup Statement stmt = conn.createStatement();
            bol = stmt.execute(sql);
            System.out.println("\n== Begin Query Results ======================");
            System.out.println("== End Query Results =======================\n\n");
        } catch (Exception e) {
            return e.getMessage();
        }
        return "成功";
    }

    @Override
    public Map<String,Object> count(String sql) {
        Map<String,Object> map = new HashMap<>();
        String bol = "";
        try {
            Class.forName(driver);
            @Cleanup Connection conn = DriverManager.getConnection(url,username,password);
            @Cleanup Statement stmt = conn.createStatement();
            @Cleanup ResultSet rs = stmt.executeQuery(sql);
            System.out.println("\n== Begin Query Results ======================");
            while (rs.next()) {
                // the example query returns one String column
//                System.out.println(rs.getString(1));
                map.put("count",rs.getString("count"));
            }
            System.out.println("== End Query Results =======================\n\n");
        }  catch (Exception e) {
            map.put("error",e.getMessage());
            return map;
        }
        return map;
    }

    @Override
    public Map<String, Object> countJQ(String sql) {
        Map<String,Object> map = new HashMap<>();
        String bol = "";
        try {
            Class.forName(driverJQ);
            @Cleanup Connection conn = DriverManager.getConnection(urlJQ,usernameJQ,passwordJQ);
            @Cleanup Statement stmt = conn.createStatement();
            @Cleanup ResultSet rs = stmt.executeQuery(sql);
            System.out.println("\n== Begin Query Results ======================");
            while (rs.next()) {
                // the example query returns one String column
//                System.out.println(rs.getString(1));
                map.put("count",rs.getString("count"));
            }
            System.out.println("== End Query Results =======================\n\n");
        } catch (Exception e) {
            map.put("error",e.getMessage());
            return map;
        }
        return map;
    }

    @Override
    public String create(String sql) {
        boolean bol = false;
        try {
            Class.forName(driver);
            @Cleanup Connection conn = DriverManager.getConnection(url,username,password);
            @Cleanup Statement stmt = conn.createStatement();
            bol = stmt.execute(sql);
            System.out.println("\n== Begin Query Results ======================");
            System.out.println("== End Query Results =======================\n\n");
        } catch (Exception e) {
            return "异常"+e.getMessage();
        }
        return "成功";
    }


    @Override
    public Map<String,Object> countHive(String sql) {
        Map<String,Object> map = new HashMap<>();
        String bol = "";
        try {
            Class.forName(driverHive);
            @Cleanup Connection conn = DriverManager.getConnection(urlHive,usernameHive,passwordHive);
            @Cleanup Statement stmt = conn.createStatement();
            @Cleanup ResultSet rs = stmt.executeQuery(sql);
            System.out.println("\n== Begin Query Results ======================");
            while (rs.next()) {
                // the example query returns one String column
                map.put("count",rs.getString("count"));
            }
            System.out.println("== End Query Results =======================\n\n");
        } catch (Exception e) {
            map.put("error",e.getMessage());
            return map;
        }
        return map;
    }

    @Override
    public Map<String, Object> showTableHive(String dbTableName) {
        Map<String,Object> map = new HashMap<>();
        String showSQL = "SHOW CREATE TABLE {dbTableName}";
        String show = "";
        try {
            Class.forName(driverHiveJQ);
            @Cleanup Connection conn = DriverManager.getConnection(urlHiveJQ,usernameHiveJQ,passwordHiveJQ);
            @Cleanup Statement stmt = conn.createStatement();
            //30分钟等待返回结果时长
            stmt.setQueryTimeout(1800);
            @Cleanup ResultSet rs = stmt.executeQuery(showSQL.replace("{dbTableName}",dbTableName));
            System.out.println("\n== Begin Query Results ======================");
            while (rs.next()) {
                // the example query returns one String column
//                map.put("show",rs.getString(1));
                show += rs.getString(1)+"\r\n";
            }
            map.put("show",show);
            System.out.println("== End Query Results =======================\n\n");
        } catch (Exception e) {
            map.put("error",e.getMessage());
            return map;
        }
        return map;
    }

    @Override
    public Map<String, Object> createTableHive(String sql,String dbTableName) {
        sql = StrUtil.replace(sql,dbTableName,tarPrefix+dbTableName);
        Map<String,Object> map = new HashMap<>();
        String delSQL = "DROP TABLE IF EXISTS {dbTableName}";
        map.put("sql",sql);
        try {
            Class.forName(driverHive);
            @Cleanup Connection conn = DriverManager.getConnection(urlHive,usernameHive,passwordHive);
            @Cleanup Statement stmt = conn.createStatement();
            //30分钟等待返回结果时长
            stmt.setQueryTimeout(1800);
            try {
                stmt.execute(delSQL.replace("{dbTableName}",tarPrefix+dbTableName));
            } catch (SQLException e) {
                map.put("error",e.getMessage());
                return map;
            }
            stmt.execute(sql);
        } catch (Exception e) {
            map.put("error",e.getMessage());
            return map;
        }
        return map;
    }
    @Override
    public List<CreateTableDTO> showTable(String dbName,String flag) {
        String sql = "SHOW TABLES IN {dbName}";
        String showTableSQL = dbName;
        List<CreateTableDTO> dtoList = new ArrayList<>();
        String dbNameJQ = dbName;
        try {
            @Cleanup Connection conn = null;
            if(ScanCommonConstants.ClusterName.WG.value.equals(flag)){
                Class.forName(driverHiveJQ);
                conn = DriverManager.getConnection(urlHiveJQ,usernameHiveJQ,passwordHiveJQ);
            }else{
                Class.forName(driverHive);
                conn = DriverManager.getConnection(urlHive,usernameHive,passwordHive);
                dbName = tarPrefix+dbName;
            }
            @Cleanup Statement stmt = conn.createStatement();
            showTableSQL = sql.replace("{dbName}", dbName);
            //30分钟等待返回结果时长
            stmt.setQueryTimeout(1800);
            @Cleanup ResultSet rs = stmt.executeQuery(showTableSQL);
            while (rs.next()) {
                CreateTableDTO dto = new CreateTableDTO();
                dto.setDbName(dbName);
                dto.setTableName(rs.getString(1));
                dto.setDbTableName(dbNameJQ+"."+dto.getTableName());
                dtoList.add(dto);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return dtoList;
    }
}
